/*
 * PPMC.h
 *
 *  Created on: 07/06/2010
 *      Author: administrador
 */

#ifndef PPMC_H_
#define PPMC_H_
#include <string>
#include <iostream>
#include "Excepciones.h"
#include "PPMC_Arbol.h"
#include "PPMC_Hash.h"
#include "Estadistico.h"

class PPMC {

private:

	typeCaracterChar* caracteresLeidos;

	typeCaracterAscii caracterActual;

	int ordenActual;

	int obtenerOrdenActual();

	/* Obtiene un contexto de ordenActual, con clave igual a los ultimos
	 * n-ordenActual caracteres de caracteresLeidos */
	Contexto* obtenerContexto();

	/* Se agrega un contexto de un orden mayor a ordenActual, generando la clave de contexto
	 * con el caracterActual + los necesarios de caracteresLeidos */
	void agregarContexto();

	/* Agrega el ultimo caracter leido (caracterActual) al array de caracteres leidos en la ultima posicion,
	 * desplazando todos los caracteres anteriores a la izquierda */
	void agregarCaracterLeido();

	string obtenerClaveContexto(int ordenAEncontrar);

	EstrategiaPPMC* estrategia;

	unsigned int ordenMaximo;

	typeFrecuencias cantidadCaracteresLeidos;

	//Cxt sobre el cual voy a buscar
	Contexto* CtxActual;

	//Cxt maximo sobre el cual empieza la busqueda de un caracter, ultimo ctx que se actualiza cuando se encuentra
	Contexto* CtxAnterior;

	/* Devuelve el caracter del rango correspondiente a la tabla de CtxActual
	 * de acuerdo al numero */
//	char interpretarCaracter(unsigned int caracterNumero);

	/*
	 * Obtiene el string correspondiente a la clave anterior */
	string buscarClaveAnterior(string claveActual);

	/*
	 * Obtiene el string correspondiente a la clave siguiente */
	string buscarClaveSiguiente(string claveActual);

	/*
	 * Si CtxActual = 0 -> CtxAnterior = -1. Si CtxActual = 'xyz' -> CtxAnterior = 'yz' */
	Contexto* getContextoAnterior();

	/*
	 * Si CtxActual = 0 -> CtxSiguiente = 1. Si CtxActual = 'yz' -> CtxSiguiente = 'xyz'*/
	Contexto* getContextoSiguiente();

	void inicializarVariables();

	void actualizarContextosAnteriores(typeCaracterChar caracter);

public:

	static const typeCaracterAscii FINARCH = 256;

	PPMC(int ordenMaximo, EstrategiaPPMC* estrategia);

	virtual ~PPMC();

	unsigned int getOrdenMaximo();

	void comprimir(char* rutaArchivo);

	void descomprimir(char* rutaArchivo);

	typeCaracterAscii actualizarDescompresion();

	/* Retorna el primer Contexto segun la estrategia utilizada */
//	Contexto* primerContexto();

	/* Retorna el siguiente Contexto a CtxActual, segun la estrategia utilizada */
//	Contexto* getSiguienteContexto();

	static const string claveContextoOrdenCero;
};

#endif /* PPMC_H_ */
